package org.gwtEss.table;

import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;

public abstract class HeaderTable<VO> extends Composite implements OnDemandTableFunctions<VO>{
	private FlexTable mainPanel;
	private CellFormatter mainPanelCellFormatter;
	private Cols<VO> cols;
	int INITIAL_WIDTH = 100;
	public HeaderTable(Cols<VO> cols) {
		mainPanel = new FlexTable();
		initWidget(mainPanel);
		this.cols = cols; 
		mainPanelCellFormatter = mainPanel.getCellFormatter(); 
		mainPanel.setCellPadding(0);
		mainPanel.setCellSpacing(0);
//		mainPanel.setBorderWidth(1);
		int colsSize = cols.size();
//		mainPanel.setHeight("50px");
		for (int i=0;i<colsSize; i++ ){
			ColWidget<VO> col = cols.get(i);
			HeaderWidget headerWidget = new HeaderWidgetDraggable(col, col.getSuggestedWidth()); 
			mainPanel.setWidget(0, i, headerWidget);
			mainPanel.getCellFormatter().addStyleName(0, i, "table-header");
		}
		renderVisibleCols();
		 
	}
//	@Override
//	protected void onAttach() {
//		super.onAttach();
//		resize();
//	}
	@Override
	public void setSize(String width, String height) {
		assert false: "use setPixelSize()";
	}
	@Override
	public void setWidth(String width) {
		assert false: "use setPixelWidth()";
	}
	@Override
	public void setHeight(String height) {
		assert false: "use setPixelHeight()";
	}
	@Override
	public void setPixelSize(int width, int height) {
		// TODO Auto-generated method stub
		super.setPixelSize(width, height);
	}
	public void setPixelHeight(int height) {
		Window.alert("toso");
	}
	public void setPixelWidth(int width) {
		Window.alert("toso");

	}
//	HeaderWidgetDraggable sortColHeaderWidget; 
	class HeaderWidgetDraggable extends HeaderWidget{
		ColWidget<VO> col;
		private int currIndex, startWidth, rightSideWidgetStartWidth;
		private HeaderWidgetDraggable rightWidget; 
		public HeaderWidgetDraggable(ColWidget<VO> col, int suggestedWidth) {
			super(cols, col, suggestedWidth);
			col.setColWidth(suggestedWidth);
			this.col = col; 
		}
		@Override
		public void onDragStart(int mouseX, int mouseY) {
			startWidth = getOffsetWidth();
			currIndex = findWidgetIndex(this);
			if (currIndex < mainPanel.getCellCount(0)){
				rightWidget = (HeaderWidgetDraggable)mainPanel.getWidget(0, currIndex+1);
				rightSideWidgetStartWidth = rightWidget.getOffsetWidth();
			}
			super.onDragStart(mouseX, mouseY);
		}
		@Override
		public void onDragEnd(int mouseX, int mouseY, int deltaX, int deltaY) {
			super.onDragEnd(mouseX, mouseY, deltaX, deltaY);
			col.setColWidth(getOffsetWidth());
			rightWidget.col.setColWidth(rightWidget.getOffsetWidth());
			onResizeEnd(col, rightWidget.col);
		}
		@Override
		public void onDrag(int mouseX, int mouseY, int deltaX,
				int deltaY) {
			super.onDrag(mouseX, mouseY, deltaX, deltaY);
			boolean rightWidgetWidthChanged = false;
			if (currIndex < mainPanel.getCellCount(0)){
//				System.out.println("----" + (startWidth - getOffsetWidth()));
				rightWidgetWidthChanged = ((HeaderWidget)rightWidget).setPixelWidth(rightSideWidgetStartWidth + (startWidth - getOffsetWidth()));
			}
			int mouseContainingWidgetIndex = findContainingWidget(mouseX, currIndex);//currIndex + (deltaX > 0? -1: 1);
//			System.out.println("mouseContainingWidgetIndex : " + mouseContainingWidgetIndex);
			System.out.println("width---" + getOffsetWidth());
			if (mouseContainingWidgetIndex == -1 || mouseContainingWidgetIndex == currIndex)
				return;
//			swapWidgets(currIndex, mouseContainingWidgetIndex);
		}
		private int findWidgetIndex(HeaderWidgetDraggable widget) {
			int cellCount = mainPanel.getCellCount(0); 
			for (int i=0; i<cellCount; i++){
				Widget w = mainPanel.getWidget(0, i);
				if (w == widget)
					return i;
			}
			return -1;
		}

		private void swapWidgets(int index1, int index2){
			Widget widget1 = mainPanel.getWidget(0, index1);
			Widget widget2 = mainPanel.getWidget(0, index2);
			mainPanel.remove(widget1);
			mainPanel.remove(widget2);
			mainPanel.setWidget(0, index2, widget1);
			mainPanel.setWidget(0, index1, widget2);
			int w1Width = widget1.getOffsetWidth();
			int w2Width = widget2.getOffsetWidth();
			widget1.setPixelSize(w2Width, widget2.getOffsetHeight());
			widget2.setPixelSize(w1Width, widget1.getOffsetHeight());
		}

		private int findContainingWidget(int mouseX, int currIndex){
			int[] indexes = {}; 
			int mainPanelSize = mainPanel.getCellCount(0);
			if (currIndex == 0 && mainPanelSize == 1) indexes = new int[]{currIndex};
			else if (currIndex == 0 && mainPanelSize > 1) indexes = new int[]{currIndex, currIndex + 1};
			else if (currIndex > 0 && currIndex == mainPanelSize) indexes = new int[]{currIndex, currIndex - 1};
			else if (currIndex > 0 && currIndex < mainPanelSize) indexes = new int[]{currIndex, currIndex - 1, currIndex + 1};
			int indexesSize = indexes.length;
			
			for (int i=0; i < indexesSize; i++){
				Element el = mainPanelCellFormatter.getElement(0, indexes[i]);			
				if (mouseX > el.getAbsoluteLeft()  && mouseX < el.getAbsoluteRight() )
					return indexes[i];
			}
			return -1; 
		}

//		@Override
//		public int getContainerWidth() {
//			return mainPanel.getCellFormatter().get;
//		}
		@Override
		public int getContainerHeight() {
			return mainPanelCellFormatter.getElement(0, cols.indexOf(col)).getOffsetHeight();
		}

		@Override
		public void onColVisibilityChanged(Cols cols) {
			renderVisibleCols();
			HeaderTable.this.onColVisibilityChanged(cols);
		}

		@Override
		public int getContainerWidth() {
			int widgetIndex = findWidgetIndex(this); 
			return mainPanel.getCellFormatter().getElement(0, widgetIndex).getOffsetWidth();
		}
		@Override
		public void onSortAsc() {
//			col.setSortAsc(true);
//			setSortIndicatorState();//TODO: some error here 
//			if (sortColHeaderWidget != null){
//				sortColHeaderWidget.clearSortIndicator();
//			}
//			sortColHeaderWidget = this;
			onSort(col, true);
		}
		
		@Override
		public void onSortDsc() {
//			col.setSortAsc(false);
//			setSortIndicatorState();//TODO: some error here 
//			if (sortColHeaderWidget != null)
//				sortColHeaderWidget.clearSortIndicator();
//			sortColHeaderWidget = this;
			onSort(col, false);
		}
	}
	interface HasTextArea{
		void setText(String text);
	}

	public abstract void onColVisibilityChanged(Cols<VO> cols);
	private void renderVisibleCols() {
		int colsSize = cols.size();
		for (int i=0; i<colsSize; i++)
			mainPanelCellFormatter.setVisible(0, i, cols.get(i).isVisible());
	}
	private void resize() {
		int colsSize = cols.size();
		for (int i=0; i<colsSize; i++)
			((HeaderWidget<VO>)mainPanel.getWidget(0, i)).resize();
	}
}
